<template>
  <div class="file-preview-container">

    <!-- 加载状态 -->
    <div v-if="loading" class="loading">文件加载中...</div>

    <!-- DOCX 预览 -->
    <vue-office-docx v-if="fileType === 'docx'" :src="fileUrl" @rendered="onRendered" @error="onError" />

    <!-- Excel 预览 -->
    <vue-office-excel v-else-if="fileType === 'xlsx' || fileType === 'xls'" :src="fileUrl" :options="options"
      @rendered="onRendered" @error="onError" />

    <!-- PDF 预览 -->
    <vue-office-pdf v-else-if="fileType === 'pdf' && loading == false" :src="fileUrl" @rendered="onRendered"
      @error="onError" />

    <!-- 不支持的文件类型提示 -->
    <div v-else class="unsupported-type">
      不支持预览此文件类型: {{ fileType }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import VueOfficeDocx from '@vue-office/docx'
import VueOfficeExcel from '@vue-office/excel'
import VueOfficePdf from '@vue-office/pdf'
import '@vue-office/docx/lib/index.css'
import '@vue-office/excel/lib/index.css'

const props = defineProps({
  fileUrl: {
    type: String,
    required: true
  },
  fileName: {
    type: String,
    default: ''
  }
})

const loading = ref(true);
const options = ref({
  xls: false,       //预览xlsx文件设为false；预览xls文件设为true
  minColLength: 0,  // excel最少渲染多少列，如果想实现xlsx文件内容有几列，就渲染几列，可以将此值设置为0.
  minRowLength: 0,  // excel最少渲染多少行，如果想实现根据xlsx实际函数渲染，可以将此值设置为0.
  widthOffset: 10,  //如果渲染出来的结果感觉单元格宽度不够，可以在默认渲染的列表宽度上再加 Npx宽
  heightOffset: 10, //在默认渲染的列表高度上再加 Npx高
  beforeTransformData: (workbookData: any) => { return workbookData }, //底层通过exceljs获取excel文件内容，通过该钩子函数，可以对获取的excel文件内容进行修改，比如某个单元格的数据显示不正确，可以在此自行修改每个单元格的value值。
  transformData: (workbookData: any) => { return workbookData }, //将获取到的excel数据进行处理之后且渲染到页面之前，可通过transformData对即将渲染的数据及样式进行修改，此时每个单元格的text值就是即将渲染到页面上的内容
})

// 根据文件名或URL获取文件类型
const fileType = computed(() => {
  if (props.fileName) {
    const extension = props.fileName.split('.').pop()?.toLowerCase()
    return extension || ''
  }
  const url = props.fileUrl.toLowerCase()
  if (url.endsWith('.docx')) return 'docx'
  if (url.endsWith('.xlsx')) return 'xlsx'
  if (url.endsWith('.xls')) return 'xls'
  if (url.endsWith('.pdf')) return 'pdf'
  return ''
})

const onRendered = () => {
  loading.value = false;
}

const onError = (error: Error) => {
  loading.value = false
  console.error('文件渲染失败:', error)
}

// 监听文件URL变化
watch(() => props.fileUrl, (_newPath) => {
  loading.value = true;
})
</script>

<style scoped>
.file-preview-container {
  width: 100%;
  height: 100%;
  position: relative;
}

.loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 10px 20px;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  border-radius: 4px;
}

.unsupported-type {
  padding: 20px;
  text-align: center;
  color: #f56c6c;
}

/* 调整Excel预览样式 */
.vue-office-excel {
  /* 表格容器 */
  padding: 10px;
  overflow: auto;

  /* 表格样式 */
  table {
    min-width: 100%;
    border-collapse: collapse;
  }

  /* 表头样式 */
  thead th {
    background: #f0f0f0;
    position: sticky;
    top: 0;
    z-index: 10;
  }

  /* 单元格样式 */
  td,
  th {
    border: 1px solid #e0e0e0;
    padding: 6px 10px;
    min-width: 80px;
  }

  /* 斑马纹效果 */
  tr:nth-child(even) {
    background-color: #f9f9f9;
  }

  /* 冻结首列 */
  td:first-child,
  th:first-child {
    position: sticky;
    left: 0;
    background: white;
    z-index: 5;
  }

  .vue-office-excel footer,
  .vue-office-excel .footer {
    display: none !important;
  }

}
</style>